package io.chenglicun.modules.clc.service.dataset.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.JsonObject;
import com.qiniu.util.Json;
import io.chenglicun.common.page.PageData;
import io.chenglicun.common.service.impl.CrudServiceImpl;
import io.chenglicun.common.constant.Constant;
import io.chenglicun.common.utils.ConvertUtils;
import io.chenglicun.common.utils.JsonUtils;
import io.chenglicun.common.utils.excel.MyExcelUtils;
import io.chenglicun.modules.clc.dao.dataset.ClcDataColumnDao;
import io.chenglicun.modules.clc.dao.dataset.ClcDataContentDao;
import io.chenglicun.modules.clc.dao.dataset.ClcDataSetDao;
import io.chenglicun.modules.clc.dao.dataset.ViewDataSetColumnDao;
import io.chenglicun.modules.clc.dto.dataset.ClcDataContentDTO;
import io.chenglicun.modules.clc.entity.dataset.ClcDataColumnEntity;
import io.chenglicun.modules.clc.entity.dataset.ClcDataContentEntity;
import io.chenglicun.modules.clc.entity.dataset.ClcDataSetEntity;
import io.chenglicun.modules.clc.entity.dataset.ViewDataSetColumnEntity;
import io.chenglicun.modules.clc.service.dataset.ClcDataContentService;
import io.chenglicun.modules.security.user.SecurityUser;
import io.chenglicun.modules.sys.dao.SysUserDao;
import io.chenglicun.modules.sys.entity.SysUserEntity;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据内容
 *
 * @author pipi 1151485299@qq.com
 * @since 1.0 2024-03-04
 */
@Service
public class ClcDataContentServiceImpl extends CrudServiceImpl<ClcDataContentDao, ClcDataContentEntity, ClcDataContentDTO> implements ClcDataContentService {

    @Autowired
    private ClcDataColumnDao columnDao;
    @Autowired
    private ClcDataContentDao contentDao;

    @Autowired
    private ClcDataSetDao setDao;
    @Autowired
    private ViewDataSetColumnDao viewDataSetColumnDao;

    @Override
    public QueryWrapper<ClcDataContentEntity> getWrapper(Map<String, Object> params) {
        QueryWrapper<ClcDataContentEntity> wrapper = new QueryWrapper<>();

        return wrapper;
    }


    @Override
    public String importExcel(Long moduleId, MultipartFile file) throws Exception {

        JSONArray array = MyExcelUtils.readMultipartFile(file);
        System.out.println("导入数据为:" + array);
        //todo
        if (array == null || array.size() <= 0)
            return "数据为空";
        // 对比模板和sheet名称
        Workbook workbook = MyExcelUtils.getWorkbook(file, null);
        String sheetName = workbook.getSheetAt(0).getSheetName();
        // 获取模板名称
        ClcDataSetEntity clcDataSetEntity = setDao.selectById(moduleId);
        if (StringUtils.isEmpty(sheetName) || !sheetName.equals(clcDataSetEntity.getName())) {
            return "模板错误";
        }
        //1.根据模板id, 查询该模板需要哪些字段


        List<ViewDataSetColumnEntity> columnNameList = viewDataSetColumnDao.selectList(new QueryWrapper<ViewDataSetColumnEntity>().lambda().eq(ViewDataSetColumnEntity::getDataSetId, moduleId));
        Map<String, Long> nameId = new HashMap<>();
        for (ViewDataSetColumnEntity view : columnNameList) {
            nameId.put(view.getName(), view.getColumnId());
        }
        Long tim = new Date().getTime();
        for (int i = 0; i < array.size(); i++) {
            JSONObject json = array.getJSONObject(i);
            //2.匹配模板字段与excel导入字段
            for (String k : json.keySet()) {
                if ("rowNum".equals(k))
                    continue;
                ClcDataContentEntity entity = new ClcDataContentEntity();
                entity.setSetId(moduleId);
                entity.setRowNum(Long.valueOf(i + "" + tim));
                entity.setColumnId(nameId.get(k));
                entity.setValue(json.getString(k));
                //3.保存字段、值
                try {
                    contentDao.insert(entity);
                } catch (Exception e) {
                    return "字段：【" + k + "】有误，导入已终止。";
                }

            }
        }
        workbook.close();
        return "导入完成";

    }

    @Override
    public PageData<ClcDataContentDTO> getPage(Map<String, Object> params) {
        System.out.println(params);
        // 获取行号
        if (params.get("setId") == null && StringUtils.isEmpty(params.get("setId").toString())) {
            return new PageData<>(null, 0);
        }
        Integer page = 1;
        Integer limit = 10;
        if (params.get("page") != null && StringUtils.isNotEmpty(params.get("page").toString())) {
            page = Integer.valueOf(params.get("page").toString());
        }
        if (params.get("limit") != null && StringUtils.isNotEmpty(params.get("limit").toString())) {
            limit = Integer.valueOf(params.get("limit").toString());
        }

        Integer limitStart = page * limit - limit;
        Integer limitEnd = limitStart + limit;
        QueryWrapper<ClcDataContentEntity> pageIdsWrapper = new QueryWrapper<>();
        pageIdsWrapper.lambda().select(ClcDataContentEntity::getRowNum).eq(ClcDataContentEntity::getSetId, params.get("setId")).groupBy(ClcDataContentEntity::getRowNum).last("limit " + limitStart + "," + limitEnd);
        QueryWrapper<ClcDataContentEntity> queryWrapperCount = new QueryWrapper<>();
        queryWrapperCount.select("count(row_num)");
        queryWrapperCount.lambda().select(ClcDataContentEntity::getRowNum).eq(ClcDataContentEntity::getSetId, params.get("setId")).groupBy(ClcDataContentEntity::getRowNum);
        if (params.get("keyStr") != null && StringUtils.isNotEmpty(params.get("keyStr").toString())) {
            pageIdsWrapper.lambda().like(ClcDataContentEntity::getValue, params.get("keyStr"));
            queryWrapperCount.lambda().like(ClcDataContentEntity::getValue, params.get("keyStr"));
        }
        List<ClcDataContentEntity> clcDataContentEntities = baseDao.selectList(pageIdsWrapper);

        List<Map<String, Object>> maps = baseDao.selectMaps(queryWrapperCount);
        Integer total = maps.size();
        if (clcDataContentEntities == null || clcDataContentEntities.size() <= 0)
            return new PageData<>(null, 0);
        List<Long> rowNums = new ArrayList<>();
        for (ClcDataContentEntity rowNum : clcDataContentEntities) {
            rowNums.add(rowNum.getRowNum());
        }
        List<ClcDataContentEntity> list = baseDao.selectList(new QueryWrapper<ClcDataContentEntity>().lambda().eq(ClcDataContentEntity::getSetId, params.get("setId")).in(ClcDataContentEntity::getRowNum, rowNums));
        // 以行号分组
        Map<Long, List<ClcDataContentEntity>> map = new HashMap<>();
        for (ClcDataContentEntity l : list) {
            if (!map.containsKey(l.getRowNum())) {
                map.put(l.getRowNum(), new ArrayList<>());
            }
            map.get(l.getRowNum()).add(l);
        }
        List<List<ClcDataContentEntity>> data = new ArrayList<>();
        for (Long k : map.keySet()) {
            data.add(map.get(k));
        }
        PageData pageData = new PageData(data, total);
        return pageData;
    }


    @Override
    public Map<String, Object> getJsonAllBySetIds(String[] setIds, String key) {
        // 获取columnId 目前固定字段名称 JSON
        ClcDataColumnEntity column = columnDao.selectOne(new QueryWrapper<ClcDataColumnEntity>().lambda().eq(ClcDataColumnEntity::getName, "JSON").last("limit 0,1"));
        if (column == null)
            return null;
        Long columnId = column.getId();
        // 根据条件筛选查询多少行号
        QueryWrapper<ClcDataContentEntity> queryRowNum = new QueryWrapper<>();
        QueryWrapper<ClcDataContentEntity> queryJson = new QueryWrapper<>();
        queryJson.lambda().eq(ClcDataContentEntity::getColumnId, columnId);
        if (setIds != null && setIds.length > 0) {
            queryRowNum.lambda().in(ClcDataContentEntity::getSetId, setIds);
            queryJson.lambda().in(ClcDataContentEntity::getSetId, setIds);
        }
        if (StringUtils.isNotEmpty(key)) {
            queryRowNum.lambda().like(ClcDataContentEntity::getValue, key);
        }
        // 查询符合条件的行号
        queryRowNum.lambda().select(ClcDataContentEntity::getRowNum).groupBy(ClcDataContentEntity::getRowNum);
        List<ClcDataContentEntity> rowNumsEntitys = baseDao.selectList(queryRowNum);
        if (rowNumsEntitys == null || rowNumsEntitys.size() <= 0)
            return null;
        List<Long> rowNums = new ArrayList<>();
        for (ClcDataContentEntity rowNum : rowNumsEntitys) {
            rowNums.add(rowNum.getRowNum());
        }

        // 查询返回数据json,根据条件筛选出的行号
        queryJson.lambda().in(ClcDataContentEntity::getRowNum, rowNums);
        List<ClcDataContentEntity> contents = baseDao.selectList(queryJson);
        if (contents == null || contents.size() <= 0)
            return null;
        List<String> collect = contents.stream().map(ClcDataContentEntity::getValue).collect(Collectors.toList());

        List<Object> list = new ArrayList<>(collect.size());
        collect.forEach(t -> list.add(JSONObject.parseObject(t)));
        Map<String, Object> map = new HashMap<>();
        map.put("type", "FeatureCollection");
        map.put("features", list);
        return map;
    }

    @Autowired
    private SysUserDao userDao;

    @Override
    public List<ClcDataContentDTO> getByPoint(Long pointId, List<Object> setId) {
        // 根据pointId查询对应的数据集的值
        List<ClcDataContentEntity> entity = baseDao.selectList(new QueryWrapper<ClcDataContentEntity>().lambda().eq(ClcDataContentEntity::getValue, pointId).in(ClcDataContentEntity::getSetId, setId));
        if (entity == null || entity.size() <= 0)
            return null;
        List<Long> rowNums = new ArrayList<>();
        for (int i = 0; i < entity.size(); i++) {
            rowNums.add(entity.get(i).getRowNum());
        }
        // 查询的当前行的所有信息
        List<ClcDataContentEntity> row = baseDao.selectList(new QueryWrapper<ClcDataContentEntity>().lambda().in(ClcDataContentEntity::getSetId, setId).in(ClcDataContentEntity::getRowNum, rowNums));
        if (row == null || row.size() <= 0)
            return null;
        List<ClcDataContentDTO> dtos = ConvertUtils.sourceToTarget(row, ClcDataContentDTO.class);
        // 获取当前行的所有字段
        List<Long> columnIds = new ArrayList<>();
        for (ClcDataContentDTO dto : dtos) {
            columnIds.add(dto.getColumnId());
        }
        List<ClcDataColumnEntity> columnEntities = columnDao.selectList(new QueryWrapper<ClcDataColumnEntity>().lambda().in(ClcDataColumnEntity::getId, columnIds));

        // 判断字段的数据等级，如果用户权限不一致，则移除
        SysUserEntity sysUserEntity = userDao.selectById(SecurityUser.getUserId());
        Map<Long, ClcDataColumnEntity> map = new HashMap<>();
        for (ClcDataColumnEntity columnEntity : columnEntities) {
            if (columnEntity.getDataLevel() != null && sysUserEntity.getDataLevel() != null && columnEntity.getDataLevel().compareTo(sysUserEntity.getDataLevel()) <= 0)
                map.put(columnEntity.getId(), columnEntity);
        }
        List<ClcDataContentDTO> resDtos = new ArrayList<>();
        for (int i = 0; i < dtos.size(); i++) {
            if (map.containsKey(dtos.get(i).getColumnId())) {
                dtos.get(i).setColumnName(map.get(dtos.get(i).getColumnId()).getName());
                dtos.get(i).setType(map.get(dtos.get(i).getColumnId()).getType());
                resDtos.add(dtos.get(i));
            }
        }
        return resDtos;
    }
}